package com.example.project.exception;

import com.example.project.domain.response.Response;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.lang.NonNull;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
/**
 * 全局异常处理类
 */
@Slf4j
public class GlobalExceptionHandler implements HandlerExceptionResolver {
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public ModelAndView resolveException(
            @NonNull HttpServletRequest request,
            @NonNull HttpServletResponse response,
            Object handler,
            @NonNull Exception ex) {
        try {
            // 设置响应内容类型为 JSON
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setCharacterEncoding("UTF-8");

            // 根据异常类型构造 Response 对象
            Response<Void> errorResponse;
            if (ex instanceof BusinessException businessEx) {
                // 处理自定义异常(抛出异常但是没有在业务在捕获的异常在此处理)
                log.error("<业务异常> code:{}, message:{}", businessEx.getStatusCode(),ex.getMessage());
                errorResponse = Response.error(businessEx.getStatusCode(), businessEx.getMessage());
                response.setStatus(businessEx.getStatusCode());
            } else {
                // 处理其他未捕获的异常
                log.error("未捕获的异常: {}", ex.getMessage());
                errorResponse = Response.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器内部错误");
                response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            }

            // 将 Response 对象序列化为 JSON 并写入响应
            objectMapper.writeValue(response.getWriter(), errorResponse);
        } catch (IOException e) {
            // 处理序列化或写入失败的情况
            log.error("异常响应写入失败: {}", e.getMessage(), e);
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }

        // 返回 null，表示异常已手动处理，不需要视图渲染
        return null;
    }
}